package org.scohen.juploadr.ui.thumbnail;

import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.widgets.Display;
import org.scohen.juploadr.ui.ReusableUIFactory;

public class SwtThumbnailBuilder implements ThumbnailBuilder {
    private float scaleFactor = 0.0f;
    private static int total = 0;

    public Image buildSquareThumbnail(Image large, Point thumbnailSize) {
        return getThumbnail(large, thumbnailSize,true);
    }

    public Image buildLargeThumbnail(Image large,Point requestedSize) {
        return getThumbnail(large, requestedSize,false);
    }

    private Image getThumbnail(Image large, Point scaledSize, boolean square) {
        Image scaled = null;
        long time = System.currentTimeMillis();
        Display display = ReusableUIFactory.getInstance().getDisplay();

        ImageData data = large.getImageData();

        scaled = new Image(display, scaledSize.x, scaledSize.y);

        GC gfx = new GC(scaled);
        // scaleTransform(display, large, gfx);
        if (square) {
            scaleDrawSquareImage(large, data, scaledSize, gfx);
        } else {
            scaleDrawImage(large, data, scaledSize, gfx);
        }
        gfx.dispose();
        total += System.currentTimeMillis() - time;
        System.out.printf("Scale (%s) took %d Total: %d\n", (square)?"square":"large", System.currentTimeMillis() - time, total);

        return scaled;
    }

    /**
     * @param display
     * @param orig
     * @param gfx
     */
    private void scaleTransform(Display display, Image orig, GC gfx) {
        Transform tx = new Transform(display);
        tx.scale(scaleFactor, scaleFactor);
        gfx.setTransform(tx);
        gfx.drawImage(orig, 0, 0);
    }

    /**
     * @param orig
     * @param data
     * @param scaledSize
     * @param gfx
     */
    private void scaleDrawImage(Image orig, ImageData data, Point scaledSize, GC gfx) {
        gfx.drawImage(orig, 0, 0, data.width, data.height, 0, 0, scaledSize.x, scaledSize.y);
    }

    private void scaleDrawSquareImage(Image orig, ImageData data, Point scaledSize, GC gfx) {
        int smallestSide = Math.min(data.width, data.height);
        gfx.drawImage(orig, 0, 0, smallestSide, smallestSide, 0, 0, scaledSize.x, scaledSize.y);
    }

    private Point getScaledSize(ImageData data, int desiredWidth, int desiredHeight) {
        scaleFactor = 0.0f;
        if (data.width > data.height) {
            // width > height, normal image
            scaleFactor = (float) desiredWidth / (float) data.width;
        } else {
            // height > width, flipped image
            scaleFactor = (float) desiredHeight / (float) data.height;
        }
        return new Point((int) Math.ceil(data.width * scaleFactor), (int) Math.ceil(data.height * scaleFactor));
    }

}
